/*	BehaviorTree class declaration
 *  The BehaviorTree class is designed to initialize, hold reference to, manage, and cleanup the BehaviorTree
 *	for our AI.  Actual traversal of the tree will start with a call into BehaviorTree.  Implements the singleton
 *	class.
 *
*/

#ifndef BEHAVIORTREE_H_
#define	BEHAVIORTREE_H_

//Basic/abstract class includes
#include "Behavior.h"
#include "Decider.h"
#include "Sequence.h"
#include "Singleton.h"

//Behavior decorators
#include "BuildAirSequenceDecorator.h"
#include "BuildInfantrySequenceDecorator.h"
#include "BuildMechSequenceDecorator.h"
#include "BuildUnitsSequenceDecorator.h"
#include "ProductionBuildingSequenceDecorator.h"
#include "ResearchBuildingSequenceDecorator.h"
#include "ResetBehaviorDecorator.h"
#include "GroundAttackSequenceDecorator.h" 

//Attack behaviors
#include "GroundAttack.h"
#include "MechAttack.h"
#include "AirAttack.h"

//Defense behaviors
#include "BaseDefense.h"

//Build buildings behaviors
#include "BuildAcademy.h"
#include "BuildArmory.h"
#include "BuildBarracks.h"
#include "BuildCommandCenter.h"
#include "BuildComsat.h"
#include "BuildControlTower.h"
#include "BuildDepot.h"
#include "BuildEngineeringBay.h"
#include "BuildFactory.h"
#include "BuildMachineShop.h"
#include "BuildPhysicsLab.h"
#include "BuildRefinery.h"
#include "BuildScienceFacility.h"
#include "BuildStarport.h"

//Build unit behaviors
#include "BuildFirebat.h"
#include "BuildGoliath.h"
#include "BuildMarine.h"
#include "BuildMedic.h"
#include "BuildScienceVessel.h"
#include "BuildSCV.h"
#include "BuildSiegeTank.h"
#include "BuildWraith.h"
#include "BuildValkyrie.h"
#include "BuildVulture.h"

//Gather behaviors
#include "Gather.h"
#include "GatherGas.h"

//Research behaviors
#include "ResearchStim.h"
#include "ResearchUpgrade.h"
#include "ResearchTech.h"

//Scout behaviors
#include "UseComsat.h"
#include "Scout.h"
#include "VultureHarass.h"

//Misc behaviors
#include "RallyAndPatrol.h"

#define BT BehaviorTree::GetInstancePtr() // Convenience for accessing BehaviorTree

class BehaviorTree : public Singleton<BehaviorTree>
{
public:
	friend class Singleton<BehaviorTree>;
	
	//Called once at the beginning to setup the tree.
	void Initialize();

	//Called every OnFrame() (or multiple thereof) to traverse the tree.
	void Update();

	//Called to cleanup tree if needed.
	void Finalize();

	/*	Method to drive/initialize recursive traversal of tree for debug/printing purposes
	 *
	*/
	void DebugPrintTree();
	
private:
	//Singleton design pattern; keep these private.
	BehaviorTree() {}
	//Singleton design pattern; keep these private.
	~BehaviorTree();

	/*	Create Defend branch.
	 *
	*/
	void InitDefend();

	/*	Create Attack branch.
	 *
	*/
	void InitAttack();

	/*	Create Attack Ground Units branch.
	*
	*/
	void InitAttackGroundUnits(BaseBehavior* attack);

	/*	Create Attack Air Units branch.
	*
	*/
	void InitAttackAirUnits(BaseBehavior* attack);

	/*	Create Defend from Ground Units branch.
	*
	*/
	void InitDefendGroundUnits(BaseBehavior* defend);

	/*	Create Defend from Air Units branch.
	*
	*/
	void InitDefendAirUnits(BaseBehavior* defend);

	/*	Create Build branch.
	 *
	*/
	void InitBuild();

	/*	Create Build Units sequence.
	 *
	*/
	void InitBuildUnits(BaseBehavior*);

	void InitBuildMech(BaseBehavior* build);

	void InitBuildInfantry(BaseBehavior* build);

	void InitBuildAir(BaseBehavior* build);

	/*	Create Build Buildings selector.
	 *
	*/
	void InitBuildBuildings(BaseBehavior*);
	void InitBuildProductionBuildings(BaseBehavior* build);
	void InitBuildResearchBuildings(BaseBehavior* build);

	/*	Create Gather branch.
	 *
	*/
	void InitGather();

	void InitResearch();

	/*	Create Scout behavior.
	 *
	*/
	void InitScout();

	

	/*	Method to recursively traverse tree for debug/printing purposes
	 *	@param current Pointer to BaseBehavior currently being expanded/printed
	 *	@param depth Current depth of tree exploration
	*/
	void DebugPrintTreeTraversal(BaseBehavior* current, int depth, bool last, unsigned int formatBitFlag);

	static char* BoolToString(bool inc)	{	if(inc)	{	return	"True";	}
											else	{	return	"False";}
										}
	BaseBehavior* root;
	char debugTabs[30];
};

#endif
